using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using JwtBearerDemo.Config;
using JwtBearerDemo.Model;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;

namespace JwtBearerDemo.Controllers;

[ApiController]
public class AccountController : ControllerBase {
  [AllowAnonymous]
  [HttpPost("api/login")]
  public IActionResult Login (string username, string password) {
    if (ModelState.IsValid) {
      if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
        return BadRequest(new { code = 0, message = "请输入用户名和密码" });

      if (username != "admin" || password != "123456")
        return BadRequest(new { code = 0, message = "账号错误，请重试" });
    }

    // Mock数据
    var u = UserInfo.Default();
    var exp = DateTime.Now.AddMinutes(MyConfig.Expires);

    //JwtRegisteredClaimNames.NameId、ClaimTypes.NameIdentifier和JwtRegisteredClaimNames.Sub键名有冲突，建议自定义键名或同步设置
    var claims = new[]
    {
            // 授权的基本信息
            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),                  // JWT编号
            new Claim(JwtRegisteredClaimNames.Name, username!),                                       // 用户名
            new Claim(JwtRegisteredClaimNames.NameId, u.ID),                                              // 用户ID
            new Claim(JwtRegisteredClaimNames.Sub, "MyProgram"),                                      // 主题，可以是项目名称、应用程序、用户类型、角色等
            new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),   // NotBefore
            new Claim(JwtRegisteredClaimNames.Exp, $"{new DateTimeOffset(exp).ToUnixTimeSeconds()}"),                    // Expires

            // 用户信息，尽量使用自定义名称, 尽量显式传参
            new Claim("user_id", u.ID),
            new Claim("user_group", u.Group),
            new Claim("user_name", username!),
            new Claim(ClaimTypes.Name, username!),
            new Claim(ClaimTypes.Role, u.Role),
            new Claim(ClaimTypes.NameIdentifier, u.ID),
            new Claim(ClaimTypes.Surname, u.Surname),
            new Claim(ClaimTypes.Gender, u.Gender),
            new Claim(ClaimTypes.MobilePhone, u.Phone),
            new Claim(ClaimTypes.Email, u.Email)
        };

    SecurityKey key = new SymmetricSecurityKey(MyConfig.Key);

#if 使用非对称算法
    string keyDir = Directory.GetCurrentDirectory();
    if (!RSAHelper.TryGetKeyParameters(keyDir, true, out RSAParameters keyParams)) {
      keyParams = RSAHelper.GenerateAndSaveKey(keyDir);
    }
    key = new RsaSecurityKey(keyParams);
#endif

    //不小于256位(32字节)
    var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);     //资格证书

    var token = new JwtSecurityToken(
        issuer: MyConfig.Iss,                       // 发行机构
        audience: MyConfig.Adu,                // 受众机构
        claims: claims,                                // 声明信息
        expires: exp,                                   // 主要过期时间,会覆盖JwtRegisteredClaimNames.Exp，建议数值同步
        signingCredentials: credentials);   // 资格证明

    return Ok(new {
      code = 1,
      message = "ok",
      token = new JwtSecurityTokenHandler().WriteToken(token)
    });
  }
}